<template>
  <a-drawer
    :width="340"
    :mask-closable="false"
    :visible="dataModel.visible"
    unmount-on-close
    :ok-loading="loading"
    @ok="handleOk"
    @cancel="handleCancel">
    <template #title>
      {{ dataModel.title }}
    </template>
    <div>
      <a-form
        ref="userDrawerForm"
        layout="vertical"
        :model="formData"
        :disabled="dataModel.disabled"
        :style="{width:'100%'}">
        <a-form-item
          field="username"
          :disabled="dataModel.type !== Operation.CREATE"
          label="用户名:"
          :rules="[{required: true, message:'请输入用户名'}, {match: /^[a-zA-Z0-9_-]{4,16}$/, message: '4到16位（字母，数字，下划线，减号）'}]">
          <a-input v-model="formData.username" placeholder="请输入用户名..." allow-clear />
        </a-form-item>
        <a-form-item
          field="nickname"
          label="昵称"
          :rules="[{maxLength: 16, message: '长度超限，最大16位'}]">
          <a-input v-model="formData.nickname" placeholder="请输入昵称..." allow-clear />
        </a-form-item>
        <a-form-item
          field="password"
          label="密码"
          :rules="[{required: dataModel.type !== Operation.UPDATE, message:'请输入密码'}, {match: /^\S*(?=\S{6,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/, message: '最少6位，包括至少1个大写字母，1个小写字母，1个数字，1个特殊字符'}]">
          <a-input v-model="formData.password" type="password" placeholder="请输入密码..." allow-clear />
        </a-form-item>
        <a-form-item
          field="gender"
          label="性别"
        >
          <a-select
            v-model="formData.gender"
            allow-clear
            placeholder="请选择性别..."
          >
            <a-option :value="1">男</a-option>
            <a-option :value="0">女</a-option>
          </a-select>
        </a-form-item>
        <a-form-item
          field="phone"
          label="手机号"
          :rules="[{required: true, message:'请输入手机号'}, {match: /^(?:(?:\+|00)86)?1\d{10}$/, message: '手机号格式不正确'}]">
          <a-input v-model="formData.phone" placeholder="请输入手机号..." allow-clear />
        </a-form-item>
        <a-form-item
          field="email" label="邮箱"
          :rules="[{match: /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/, message: '邮箱格式不正确'}]">
          <a-input v-model="formData.email" placeholder="请输入邮箱..." allow-clear />
        </a-form-item>
        <a-form-item field="avatar" label="头像">
          <e-single-image-upload v-model="formData.avatar"/>
        </a-form-item>
        <a-form-item
          field="rolesId" label="角色"
          :rules="[{required: true, message: '角色不能为空'}, {empty: false, message: '角色不能为空'}]">
          <a-select
            v-model:model-value="formData.rolesId"
            multiple
            allow-clear
            direction="vertical"
            :allow-search="false"
            placeholder="请选择角色列表..."
          >
            <a-option v-for="(role, index) in roles" :key="`${role.code}_${index}`" :value="role.id">{{ role.name }}
            </a-option>
          </a-select>
        </a-form-item>
        <a-form-item
          field="deptsId" label="部门"
          :rules="[{required: true, message: '部门不能为空'}, {empty: false, message: '部门不能为空'}]">
          <a-tree-select
            v-model="formData.deptsId"
            multiple
            allow-clear
            :tree-checkable="true"
            :data="depts"
            :field-names="{
                key: 'id',
                title: 'name'
            }"
            tree-check-strictly
            placeholder="请选择组织机构..."
          ></a-tree-select>
        </a-form-item>
        <a-form-item field="enabled" label="状态">
          <a-switch
            v-model:model-value="formData.enabled"
            type="round"
            :checked-value="true"
            :unchecked-value="false"
            unchecked-color="#F53F3F"
          >
            <template #checked>
              正常
            </template>
            <template #unchecked>
              异常
            </template>
          </a-switch>
        </a-form-item>
      </a-form>
    </div>
  </a-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { Message } from "@arco-design/web-vue";
import useDataModel from "@/hooks/data-model";
import ESingleImageUpload from "@/components/upload/e-single-image-upload.vue";
import useLoading from "@/hooks/loading";
import { listAll } from "@/api/modules/system/role";
import { create, findById, update } from "@/api/modules/system/user";
import { Operation } from "@/types/global";
import type { DeptVo, RoleVo, UserDto } from "@/types/modules/system";
import type { ValidatedError } from "@arco-design/web-vue/es/form/interface";
import { listTree } from "@/api/modules/system/dept";

const defaultFormData = () => ({
  id: 0,
  username: "",
  nickname: "",
  password: "",
  phone: "",
  email: "",
  avatar: "",
  rolesId: [],
  deptsId: [],
  enabled: true
});

const formData = ref<UserDto>(defaultFormData());
const userDrawerForm = ref<any>(null);
const roles = ref<RoleVo[]>([]);
const depts = ref<DeptVo[]>([]);
const { dataModel, openModel, closeModel } = useDataModel();
const { loading, setLoading } = useLoading();
const emit = defineEmits(["refresh"]);

const createHandle = async () => {
  roles.value = (await listAll()).data;
  openModel("添加用户信息", false, true, Operation.CREATE);
};

const updateHandle = async (id: number) => {
  const { data: roleVos } = await listAll()
  roles.value = roleVos;
  const { data: tree } = await listTree()
  depts.value = tree
  const { data: userVo } = await findById(id)
  const { id: uid, username, nickname, gender, phone, email, avatar, enabled, nonLocked } = userVo
  formData.value = {
      id: uid, username, nickname, gender, phone, email, avatar, enabled, nonLocked,
    rolesId: userVo.roles.map(role => role.id),
    deptsId: userVo.depts.map(dept => dept.id)
  };
  openModel("编辑用户信息", false, true, Operation.UPDATE);
};

const previewHandle = async (id: number) => {
  const { data: roleVos } = await listAll();
  roles.value = roleVos;
  const { data: userVo } = await findById(id)
  const { id: uid, username, nickname, gender, phone, email, avatar, enabled, nonLocked } = userVo
  formData.value = {
    id: uid, username, nickname, gender, phone, email, avatar, enabled, nonLocked,
    deptsId: userVo.depts?.map(dept => dept.id),
    rolesId: userVo.roles.map(role => role.id)
  };
  openModel("预览用户信息", true, false, Operation.PREVIEW);
};

const handleCancel = () => {
  closeModel();
  formData.value = defaultFormData();
  setLoading(false);
};

const handleOk = async () => {
  if (dataModel.submit) {
    setLoading(true);
    if (userDrawerForm.value) {
      userDrawerForm.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
          console.log('xxx')
        if (!errors) {
          if (dataModel.type === Operation.CREATE) {
            await create(formData.value);
            Message.success({
              content: "添加成功",
              duration: 2000
            });
          } else if (dataModel.type === Operation.UPDATE) {
            await update(formData.value);
            Message.success({
              content: "修改成功",
              duration: 2000
            });
          }

          setLoading(false);
          handleCancel();
          emit("refresh");
        } else {
          setTimeout(() => {
            setLoading(false);
          }, 1000);
        }
      });
    }
  } else {
    handleCancel();
  }
};

defineExpose({ createHandle, updateHandle, previewHandle });
</script>

<script lang="ts">
export default {
  name: "UserDrawer"
};
</script>

<style scoped>

</style>
